
/*---------------------------------------------------------------------------
   
   File name    :   endian.c
   Author       :   Nicolas Devillard
   Created on   :   July 18, 1996
   Description  :   endian determination program
                    mostly needed to determine which kind of machine
                    we are dealing with (portability issues)

 ---------------------------------------------------------------------------*/

/*
 $Id: endian.c,v 1.9 2001/01/16 15:24:38 ndevilla Exp $
 $Author: ndevilla $
 $Date: 2001/01/16 15:24:38 $
 $Revision: 1.9 $
 */

/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/

#include <stdio.h>
#include <sys/utsname.h>

void test_m(void) ;
void print_endian(void) ;

static char swift_quote[] =
"\n"
"  It is allowed on all Hands, that the primitive Way of breaking Eggs\n"
"  before we eat them, was upon the larger End: But his present Majesty's\n"
"  Grand-father, while he was a Boy, going to eat an Egg, and breaking it\n"
"  according to the ancient Practice, happened to cut one of his Fingers.\n"
"  Whereupon the Emperor his Father, published an Edict, commanding all\n"
"  his Subjects, upon great Penalties, to break the smaller End of their\n"
"  Eggs. The People so highly resented this Law, that our Histories tell\n"
"  us, there have been six Rebellions raised on that Account;... It is\n"
"  computed that eleven Thousand Persons have, at several Times, suffered\n"
"  Death, rather than submit to break their Eggs at the smaller End. Many\n"
"  hundred large Volumes have been published upon this Controversy: But\n"
"  the Books of the Big-Endians have been long forbidden...\n"
"  -Jonathan Swift's Gulliver's Travels\n"
"\n" ;



int main(int argc, char *argv[])
{
    FILE            *testfile ;
    unsigned short  s ;
    unsigned long   l ;
    float           f ;
    double          d ;
    int             i ;
    unsigned char   c ;
    struct utsname  name ;

    if (argc>1) {
        print_endian() ;
        return 0 ;
    }   

    printf(
"\n\n"
"-------------------------------------------------------------\n"
"Endian scheme and machine type size determination\n"
"-------------------------------------------------------------\n"
"Sizes: c=%lu s=%lu i=%lu l=%lu f=%lu d=%lu\n",
            (unsigned long)sizeof(char), 
            (unsigned long)sizeof(short), 
            (unsigned long)sizeof(int),
            (unsigned long)sizeof(long), 
            (unsigned long)sizeof(float), 
            (unsigned long)sizeof(double)) ;

    if ((testfile = fopen("endian_affairs", "wb")) == (FILE*)NULL) {
        printf("cannot create a file here: aborting") ;
        return -1 ;
    }
    s = (unsigned short)0xabcd ;
    l = (unsigned long)0x12345678 ;
    f = (float)2.5e-16 ;
    d = (double)3.14e32 ;

    fwrite(&s, sizeof(unsigned short), 1, testfile) ;
    fwrite(&l, sizeof(unsigned long), 1, testfile) ;
    fwrite(&f, sizeof(float), 1, testfile) ;
    fwrite(&d, sizeof(double), 1, testfile) ;
    fclose(testfile) ;

    if ((testfile = fopen("endian_affairs", "rb")) == (FILE*)NULL) {
        printf("cannot read file here: aborting") ;
        return -1 ;
    }

    printf("\n*** short:\t") ;
    for (i=0 ; i<sizeof(unsigned short) ; i++) {
        fread(&c, 1, 1, testfile) ;
        printf(" %x", c) ;
    }
    printf("\n*** long:\t") ;
    for (i=0 ; i<sizeof(unsigned long) ; i++) {
        fread(&c, 1, 1, testfile) ;
        printf(" %x", c) ;
    }
    printf("\n*** float:\t") ;
    for (i=0 ; i<sizeof(float) ; i++) {
        fread(&c, 1, 1, testfile) ;
        printf(" %x", c) ;
    }
    printf("\n*** double:\t") ;
    for (i=0 ; i<sizeof(double) ; i++) {
        fread(&c, 1, 1, testfile) ;
        printf(" %x", c) ;
    }
    printf("\n") ; 
    fclose(testfile) ;
   // remove("endian_affairs") ;
    printf("-------------------------------------------------------------\n");
    test_m() ;
//    uname(&name) ;
/*    printf("%s %s %s %s %s\n", name.nodename, name.sysname,
                               name.release, name.version,
                               name.machine);
    printf("-------------------------------------------------------------\n");
*/
    printf("end of report\n\n") ;

    return 0 ;

}

void test_m(void)
{
    int x = 1;
    printf("This machine has a") ;
    (*(char*)&x) ? printf(" Little Endian") : printf(" Big Endian") ;
    printf(" based processor\n") ;
}


void print_endian(void)
{
    struct utsname name ;
    int x = 1;

    x = (*(char*)&x) ;

    uname(&name) ;
    fprintf(stdout,
        "/*\n"
        "----------------------------------------------------------------\n"
        "  This file automatically generated by endian.c\n"
        "\n"
        "  node      : %s\n"
        "  OS        : %s\n"
        "  release   : %s\n"
        "  version   : %s\n"
        "  machine   : %s\n"
        "----------------------------------------------------------------\n"
        "\n"
        "%s"
        "*/\n"
        "#ifndef _ENDIAN_AFFAIRS_H_\n"
        "#define _ENDIAN_AFFAIRS_H_\n"
        "\n"
        "#define INTEL                 0\n"
        "#define MOTOROLA              1\n"
        "#define BYTE_ORDERING_SCHEME  %s\n"
        "#endif\n",

            name.nodename,
            name.sysname,
            name.release,
            name.version,
            name.machine,

            swift_quote,

            x ? "INTEL" : "MOTOROLA"
    );

}   
